home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
clipper
/
nfsrc21.zip
/
NWSEM.PRG
< prev
next >
Wrap
Text File
|
1992-10-17
|
18KB
|
574 lines
/*
* File......: NWSEM.PRG
* Author....: Glenn Scott
* CIS ID....: 71620,1521
* Date......: $Date: 17 Oct 1992 16:28:22 $
* Revision..: $Revision: 1.4 $
* Log file..: $Logfile: C:/nanfor/src/nwsem.prv $
*
* This is an original work by Glenn Scott and is placed in the
* public domain.
*
* Modification history:
* ---------------------
*
* $Log: C:/nanfor/src/nwsem.prv $
*
* Rev 1.4 17 Oct 1992 16:28:22 GLENN
* Leo cleaned up documentation blocks.
*
* Rev 1.3 08 Oct 1992 01:37:34 GLENN
* Added ft_nwsemUnlock() to complement ft_nwsemlock(). Modified
* the calling procedure for ft_nwsemlock() but it shouldn't break any
* existing code, although I doubt anyone's using it.
*
*
* Rev 1.2 17 Aug 1991 16:11:46 GLENN
* Oops, I forgot to comment out some test code.
*
* Rev 1.1 15 Aug 1991 23:05:34 GLENN
* Forest Belt proofread/edited/cleaned up doc
*
* Rev 1.0 28 Jun 1991 00:44:14 GLENN
* Initial revision.
*
*/
// --------------------------------------------------------------
// Semaphore Package for Novell NetWare
// --------------------------------------------------------------
#include "ftint86.ch"
#define INT21 33
#xcommand DEFAULT <v1> TO <x1> [, <vN> TO <xN> ];
=> IIF((<v1>)=NIL,<v1>:=<x1>,NIL) [; IF((<vN>)=NIL,<vN>:=<xN>,NIL)]
#define WAIT_SEMAPHORE 2
#define SIGNAL_SEMAPHORE 3
#define CLOSE_SEMAPHORE 4
// Sorry this test routine is pretty lame but it sort of gets
// the point across
#ifdef FT_TEST
#define INITIAL_SEMAPHORE_VALUE 2
#define WAIT_SECONDS 1
function main()
local nInitVal, nRc, nHandle, nValue, nOpenCnt
cls
nInitVal := INITIAL_SEMAPHORE_VALUE
FT_NWSEMOPEN( "TEST", nInitVal, @nHandle, @nOpenCnt )
qout( "Waiting ten seconds..." )
nRc := ft_nwSemWait( nHandle, 180 )
qout( "Final nRc value = " + STR( nRc ) )
inkey(0)
if nRc == 254
qout("Couldn't get the semaphore. Try again.")
quit
end
cls
@ 24, 0 say "Any key to exit"
@ 0, 0 say "Handle: " + str( nHandle )
ft_nwSemEx( nHandle, @nValue, @nOpenCnt )
while .t.
@ 23, 0 say "Semaphore test -> Open at [" + ;
alltrim(str(nOpenCnt)) + ;
"] stations, value is [" + ;
alltrim(str(nValue)) + "]"
if inkey( WAIT_SECONDS ) != 0
exit
endif
tone( nHandle,.5 )
ft_nwSemEx( nHandle, @nValue, @nOpenCnt )
end
qout( "Signal returns: " + str( ft_nwsemSig( nHandle ) ) )
qout( "Close returns: " + str( ft_nwsemClose( nHandle ) ) )
return nil
#endif
/* $DOC$
* $FUNCNAME$
* FT_NWSEMOPEN()
* $CATEGORY$
* NetWare
* $ONELINER$
* Open or create a NetWare semaphore
* $SYNTAX$
* FT_NWSEMOPEN( <cName>, <nInitVal>, <@nHandle>, <@nOpenCnt> ) -> nRc
* $ARGUMENTS$
* <cName> is the semaphore name, maximum length is 127 characters.
*
* <nInitVal> is the initial value for the semaphore. It must start
* as a positive number, to a maximum of 127.
*
* <@nHandle> is the semaphore handle. THIS MUST BE PASSED BY
* REFERENCE! On exit, <nHandle> will contain a numeric value that
* refers to the opened semaphore. You will need it to pass to
* other semaphore functions! PASS IT BY REFERENCE!
*
* <@nOpenCnt> is the number of stations that have opened the
* semaphore. THIS MUST BE PASSED BY REFERENCE! On exit, <nOpenCnt>
* will contain a numeric value.
* $RETURNS$
* nRc, a numeric result code, as follows:
*
* 0 - success
* 254 - Invalid semaphore name length
* 255 - Invalid semaphore value
*
* <nHandle> will contain the semaphore handle, and
* <nOpenCnt> will contain the number of stations that have opened
* the semaphore.
* $DESCRIPTION$
* A semaphore is simply a label that indirectly controls network
* activity. There is a semaphore name, which can be up to 127
* characters, and an associated value, which can range from 0 to
* 127.
*
* A semaphore can be used for many things, but is most often used
* to limit the number of users in an application, and to control
* access to a network resource.
*
* A semaphore essentially allows you to place locks on resources
* other than files.
*
* An application begins the process by calling FT_NWSEMOPEN().
* If the semaphore doesn't exist, NetWare will create it.
* FT_NWSEMOPEN() returns a handle that is used in other semaphore
* calls.
*
* Applications use FT_NWSEMWAIT() to wait for a semaphore to
* become available. FT_NWSEMWAIT() decrements the semaphore's
* value by 1. If the value > 0, then the application should
* be allowed to access the semaphore's resource. If the value
* goes negative, then the application is placed in a queue.
* How long your app is in the queue is determined by how you
* set the timeout parameter. If you can't get the resource in
* the time you allot, you're let out of the queue and the
* value increments by 1 again.
*
* When an application finishes with a semaphore, it should
* call FT_NWSEMSIG() to increment the value, and then
* FT_NWSEMCLOSE() to close the semaphore. When the semaphore's
* open count goes to 0, NetWare deletes it.
*
* FT_NWSEMEX() can be used to examine the value and open count
* without affecting them.
*
* For an interesting discussion on the operating system aspects
* of semaphores, check "Operating Systems Design and Implementation"
* by A. Tanenbaum, page 60. For more details on NetWare's
* semaphore facilities, refer to Charles Rose's "Programmer's
* Guide to NetWare". The "Programmer's Guide" will make an
* excellent companion guide to the source code for all NetWare
* functions in the Nanforum Toolkit.
* $EXAMPLES$
* LOCAL nInitVal, nRc, nHandle, nOpenCnt
*
* nInitVal := 2
* nRc := FT_NWSEMOPEN( "Semaphore Test", nInitVal, ;
* @nHandle, @nOpenCnt )
*
* IF nRc != 0
* QOUT =: "Error: " + STR( nRc ) )
* QUIT
* ENDIF
* $SEEALSO$
* FT_NWSEMEX() FT_NWSEMWAIT() FT_NWSEMSIG() FT_NWSEMCLOSE() FT_NWSEMLOCK()
* $END$
*/
function ft_nwSemOpen( cName, nInitVal, nHandle, nOpenCnt )
local aRegs[ INT86_MAX_REGS ], cRequest, nRet
default cName to "", ;
nInitVal to 0, ;
nHandle to 0, ;
nOpenCnt to 0
cName := iif( len( cName ) > 127, substr( cName, 1, 127 ), cName )
cRequest := chr( len( cName ) ) + cName
aRegs[ AX ] := makehi( 197 ) // C5h
aRegs[ DS ] := cRequest
aRegs[ DX ] := REG_DS
aRegs[ CX ] := nInitVal
ft_int86( INT21, aRegs )
nHandle := bin2l( i2bin( aRegs[CX] ) + i2bin( aRegs[DX] ) )
nOpenCnt := lowbyte( aRegs[ BX ] )
nRet := lowbyte( aRegs[AX] )
return iif( nRet < 0, nRet + 256, nRet )
/* $DOC$
* $FUNCNAME$
* FT_NWSEMEX()
* $CATEGORY$
* NetWare
* $ONELINER$
* Examine a NetWare semaphore's value and open count
* $SYNTAX$
* FT_NWSEMEX( <nHandle>, <@nValue>, <@nOpenCnt> ) -> nRc
* $ARGUMENTS$
* <nHandle> is the semaphore handle, returned from a previous call
* to FT_NWSEMOPEN().
*
* <@nValue> will get the current semaphore value. THIS NUMERIC
* ARGUMENT MUST BE PASSED BY REFERENCE!
*
* <@nOpenCnt> will get the current number of workstations
* that have opened the semaphore. THIS NUMERIC ARGUMENT MUST BE
* PASSED BY REFERENCE!
* $RETURNS$
* nRc, a numeric, as follows:
*
* 0 - success
* 25